package com.mjk.common.core.redis.datatype;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;

public class RedisUtils {

	private RedisUtils(){}

	public static List<String> getKeys(RedisTemplate<String, Object> redisTemplate, String key) {
		// 列出所有匹配的key
		Set<String> keySet = redisTemplate.keys(key+"*");
		if (CollectionUtils.isEmpty(keySet)) {
			return Collections.emptyList();
		}
		return new ArrayList<>(keySet);
	}
	
	// 情况一：key不存在，返回-2
	// 情况二：key存在，但没有设置超时，返回-1
	// 情况三：key存在，设置有超时时间，返回实际的秒数
	public static boolean isSetExpTime(RedisTemplate<String, Object> redisTemplate, String key) {
		Long value = redisTemplate.getExpire(key);
		if(null == value){
			return false;
		}
        return value > 0;
    }
	
	public static void remove(RedisTemplate<String, Object> redisTemplate,String key){
		redisTemplate.delete(key);
	}
	/**
	 * @description set方式设置键值对
     */
	public static void set(RedisTemplate<String, Object> redisTemplate,String key, Object value) {
		redisTemplate.opsForValue().set(key, value);
	}

	/**
	 * @description get方法根据key单个获取value
     */
	public static Object get(RedisTemplate<String, Object> redisTemplate,String key) {
		return redisTemplate.opsForValue().get(key);		
	}

	/**
	 * @description 与set方法一致，批量操作
     */

	public static void mset(RedisTemplate<String, Object> redisTemplate,Map<String, String> map) {
		redisTemplate.opsForValue().multiSet(map);
	}

	/**
	 * @description 与get方法一致，批量操作
     */
	public static List<Object> mget(RedisTemplate<String, Object> redisTemplate,List<String> listKey) {
		return redisTemplate.opsForValue().multiGet(listKey);
	}

	/**
	 * @description 设置新的键值对，并且设置有效期
	 * @param offset
	 *  有效期
	 */
	public static void setex(RedisTemplate<String, Object> redisTemplate,String key, String value, int offset) {
		redisTemplate.opsForValue().set(key, value, offset, TimeUnit.SECONDS);
	}

	/**
	 * @description 自增
     */
	public static int incrby(RedisTemplate<String, Object> redisTemplate,String key, int count) {
		Long value = redisTemplate.opsForValue().increment(key, count);
		if(null != value){
			return value.intValue();
		}
		return 0;
	}

	/**
	 * @description 自减
     */
	public static int decrby(RedisTemplate<String, Object> redisTemplate,String key, int count) {
		return incrby(redisTemplate,key,count);
	}

	/**
	 * @description 追加字符串
     */

	public static String append(RedisTemplate<String, Object> redisTemplate,String key, String value) {
		Integer result = redisTemplate.opsForValue().append(key, value);
		if(null != result){
			return result.toString();
		}
		return "0";
	}

	/**
	 * @description 获取字符串长度
     */

	public static int strlen(RedisTemplate<String, Object> redisTemplate,String key) {
		Long size = redisTemplate.opsForValue().size(key);
		if(null != size){
			return size.intValue();
		}
		return 0;
	}
	
	public static boolean exists(RedisTemplate<String, Object> redisTemplate,String key){
		return Boolean.TRUE.equals(redisTemplate.hasKey(key));
	}

    public static boolean lock(RedisTemplate<String, Object> redisTemplate, String key, String clientId, int lockExpireInSecond) {
        return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, clientId, lockExpireInSecond, TimeUnit.SECONDS));
    }

    public static boolean unlock(RedisTemplate<String, Object> redisTemplate, String key, String clientId) {
        boolean result = false;
        if (clientId.equals(redisTemplate.opsForValue().get(key))) {
            result = Boolean.TRUE.equals(redisTemplate.delete(key));
        }
        return result;
    }
}
